package com.nk.system.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import com.nk.system.beans.UserProfileBean;
import com.nk.system.utils.UI_Constants;


/**
 * Servlet Filter implementation class AuthenticationFilter
 */
public class AuthenticationFilter implements Filter {

    Logger log = Logger.getLogger(AuthenticationFilter.class);
    
    private String by_pass[] = new String[]{
    		"/login/Login.action",
			"/login/Login_init.action",
			"/login/Login_logout.action"};
    /**
     * @see Filter#destroy()
     */
    public void destroy() {
    }

    /**
     * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    	log.info("AuthenticationFilter - doFilter()");

        HttpServletRequest req = (HttpServletRequest) request;
    	HttpServletResponse res = (HttpServletResponse) response;
        HttpSession session = req.getSession(true);
        ServletContext context = session.getServletContext();
        UserProfileBean userProfileBean = (UserProfileBean) session.getAttribute(UI_Constants.SESS_ATTR_USER_ACCESS);
        
        String requestURI = req.getRequestURI();
    	requestURI = requestURI.substring(1);
    	String uri = requestURI.substring(requestURI.indexOf("/"));
        log.info("URI = "+uri);
        boolean resultAccess = false;
    	if(!isByPassURL(by_pass,uri)) {
    		
    		if (userProfileBean == null) {
                res.sendRedirect(context.getContextPath() + UI_Constants.URI_LOGIN);
                return;
            } else {
            	
            	/**
            	 * Authenticated access function menu
            	 */
            	/*boolean resultAccessMenu = true;
            	List<FunctionBean> functionList = null;
            	if(user.getRole() != null) {
            		functionList = user.getRole().getFunctionBeanList();
            	}
            	resultAccessMenu = authenticatedAccessFunction(req,functionList);
            	if(!resultAccessMenu){
            		res.sendRedirect(context.getContextPath() + UI_Constants.URI_LOGIN);
            		return;
            	}*/
            	
            	/**
                 * Validate Token
                 */
                log.info("# Start validateToken");
        		String tokenReq = req.getParameter("token");
        		log.info("# tokenReq = "+tokenReq);
        		Object tokenSess = req.getSession().getAttribute("token");
        		log.info("# tokenSess = "+tokenSess);
        		if(tokenSess != null && req.getMethod().equalsIgnoreCase("post")) {
    	    		if(!tokenSess.toString().equals(tokenReq)) {
    	    			log.info("# token is invalid. ");
    	    			req.getSession().invalidate();
    	    			res.sendRedirect(context.getContextPath() + UI_Constants.URI_LOGIN);
    	    			return;
    	    		}
        		}
        		
        		/**
        		 * Single User
        		 */
        		Object singleLoginCheck = session.getAttribute(userProfileBean.getUsername());
        		SingleLogin singleLoginSess = null;
        		if(singleLoginCheck != null) {
        			singleLoginSess = (SingleLogin)singleLoginCheck;
        		}
        		ServletContext application = session.getServletContext();
        		Object singleLoginOld = application.getAttribute(userProfileBean.getUsername());
        		if(singleLoginOld != null && singleLoginSess !=null){
        			SingleLogin singleLoginApp = (SingleLogin)singleLoginOld;
        			if(!singleLoginApp.equals(singleLoginSess)){
        				log.info("user ["+userProfileBean.getUsername()+"] is duplicated login");
        				log.info("user ["+userProfileBean.getUsername()+"] is killed, invalidate session");
        				session.invalidate();
                		res.sendRedirect(context.getContextPath() + UI_Constants.URI_LOGIN);
                		return;
        			}
        		}else {
            		Integer random = (int)(Math.random()*10000);
            		SingleLogin singleLogin = new SingleLogin();
            		singleLogin.setIpSession(req.getRemoteHost());
            		singleLogin.setRandomSession(random);
            		session.setAttribute(userProfileBean.getUsername(), singleLogin);
            		application.setAttribute(userProfileBean.getUsername(), singleLogin);
        		}
            }
    		
    		/*if(functionList != null){
        		for(FunctionBean functionBean:functionList){
            		for(MenuFunction menuFunction:functionBean.getMenuFunctionList()){ 
            			if (uri.equals("/" + menuFunction.getUrl())) {
            				log.info(" access granted");
            				resultAccess = true;
            				break;
            			}
            		}
            		if(resultAccess){
            			break;
            		}
            	}
    		}else {
    			log.info(" Don't access ");
    	    	return resultAccess;
    		}*/
    	}else {
    		resultAccess = true;
    		log.info(" access granted");
    		log.info(" by pass");
    	}

    	/**
    	 * Forward request
    	 */
        chain.doFilter(request, response);
        
    }

    /**
     * @see Filter#init(FilterConfig)
     */
    public void init(FilterConfig config) throws ServletException {
    }
    
    /*private boolean authenticatedAccessFunction(HttpServletRequest request,List<FunctionBean> functionList) {

    	*//**
    	 *  compare uri with function user
    	 *//*

    	String requestURI = request.getRequestURI();
    	requestURI = requestURI.substring(1);
    	String uri = requestURI.substring(requestURI.indexOf("/"));
        log.info("URI = "+uri);
//    	String uri = requestURI.substring(requestURI.lastIndexOf("/") + 1);

    	
    	boolean resultAccess = false;
		if(functionList != null){
    		for(FunctionBean functionBean:functionList){
        		for(MenuFunction menuFunction:functionBean.getMenuFunctionList()){ 
        			if (uri.equals("/" + menuFunction.getUrl())) {
        				log.info(" access granted");
        				resultAccess = true;
        				break;
        			}
        		}
        		if(resultAccess){
        			break;
        		}
        	}
		}else {
			log.info(" Don't access ");
	    	return resultAccess;
		}
    	
    	if(resultAccess){
        	return resultAccess;
		}else {
			log.info(" Don't access ");
	    	return resultAccess;
		}
    	
    }*/
    
    private boolean isByPassURL(String url_by_pass[], String url){
    	boolean result = false;
    	for(String urlCheck:url_by_pass){
    		if(urlCheck.equals(url)){
    			result = true;
    			break;
    		}
    	}
    	return result;
    }
    
}
